package com.nehc.nettyserver.netty;

import com.nehc.nettyserver.config.NettyServerProperties;
import com.nehc.nettyserver.netty.handler.HeartbeatHandler;
import com.nehc.nettyserver.netty.handler.WebSocketFrameHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Netty服务器通道初始化器
 * 
 * @author nehc
 * @date 2023-04-02
 */
@Component
public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {

    @Autowired
    private NettyServerProperties properties;
    
    @Autowired
    private HeartbeatHandler heartbeatHandler;
    
    @Autowired
    private WebSocketFrameHandler webSocketFrameHandler;

    @Override
    protected void initChannel(SocketChannel ch) {
        ChannelPipeline pipeline = ch.pipeline();
        
        // HTTP 编解码
        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new HttpObjectAggregator(properties.getMessage().getMaxSize()));
        
        // WebSocket
        if (properties.getMessage().isCompression()) {
            pipeline.addLast(new WebSocketServerCompressionHandler());
        }
        pipeline.addLast(new WebSocketServerProtocolHandler(
                properties.getWebsocket().getPath(), 
                null, 
                true, 
                properties.getWebsocket().getMaxFrameSize()));
        
        // 心跳检测
        pipeline.addLast(new IdleStateHandler(
                properties.getHeartbeat().getTimeout(),
                properties.getHeartbeat().getTimeout(), 
                0, 
                TimeUnit.SECONDS));
        pipeline.addLast(heartbeatHandler);
        
        // 业务逻辑处理
        pipeline.addLast(webSocketFrameHandler);
    }
} 